package com.xiaoming.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflexTest {
    /**
     * 用于测试反射的作用
     * @param args
     */
    public static void main(String[] args) throws Exception{
        getPrivateMethod();
    }

    /*
        use no arg constructor to new instance
     */
    public static void noArgInstance() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class<?> aClass = Class.forName("com.xiaoming.reflex.User");
        User user = (User)aClass.newInstance();
        user.setAge(15);
        user.setName("xiaoming");
        System.out.println(user);
    }
    /*
        use arg constructor to new instance
     */
    public static void argInstance() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> aClass = Class.forName("com.xiaoming.reflex.User");
        Constructor<?> constructor = aClass.getConstructor(String.class, Integer.class);
        User user = (User)constructor.newInstance("xiaoming", 16);
        System.out.println(user);
    }

    /*
       set field value by reflex
     */
    public static void setFieldValue() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        Class<?> aClass = Class.forName("com.xiaoming.reflex.User");
        User user = (User) aClass.newInstance();
        Field name = aClass.getDeclaredField("name");
        Field age = aClass.getDeclaredField("age");
        // 需要注意，对于私有的方法和变量，需要设置其权限
        name.setAccessible(true);
        name.set(user,"xiaolan");
        age.setAccessible(true);
        age.set(user,10);
        System.out.println(user);
    }
    /*
        invoke private method
     */
    public static void getPrivateMethod() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Class<User> userClass = (Class<User>) Class.forName("com.xiaoming.reflex.User");
        User user = userClass.newInstance();
        Method login = userClass.getDeclaredMethod("login",String.class);
        login.setAccessible(true);
        login.invoke(user,"小黑");
    }
}
